package xyz.wbsite.zentao.sdk;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.HttpUtil;
import cn.hutool.log.StaticLog;
import xyz.wbsite.zentao.sdk.execution.ZtExecutionService;
import xyz.wbsite.zentao.sdk.project.ZtProjectService;
import xyz.wbsite.zentao.sdk.task.ZtTaskService;
import xyz.wbsite.zentao.sdk.user.ZtUserService;

/**
 * 禅道客户端实例
 *
 * @author wangbing
 * @version 0.0.1
 * @since 1.8
 */
public class ZentaoInstance {

    /**
     * 客户端
     */
    private ZentaoClient client;

    /**
     * 模拟登录账户
     */
    private String account;
    /**
     * 登录信息
     */
    private String zentaosid;
    private static final int DEFAULT_CONNECT_TIMEOUT = 3 * 1000;
    private static final int DEFAULT_READ_TIMEOUT = 10 * 1000;
    private final ZtProjectService ztProjectService = new ZtProjectService(this);
    private final ZtExecutionService ztExecutionService = new ZtExecutionService(this);
    private final ZtTaskService ztTaskService = new ZtTaskService(this);
    private final ZtUserService ztUserService = new ZtUserService(this);

    public ZentaoInstance(ZentaoClient client, String account) {
        this.client = client;
        this.account = account;
    }

    public ZtProjectService getZtProjectService() {
        return ztProjectService;
    }

    public ZtExecutionService getZtExecutionService() {
        return ztExecutionService;
    }

    public ZtTaskService getZtTaskService() {
        return ztTaskService;
    }

    public ZtUserService getZtUserService() {
        return ztUserService;
    }

    private boolean login(String account) {
        String time = String.valueOf(System.currentTimeMillis() / 1000);
        String token = SecureUtil.md5(client.getServiceCode() + client.getServiceKey() + time);
        String url = StrUtil.format(client.getServiceUrl() + "/api.php?m=user&f=apilogin&account={}&code={}&time={}&token={}", account, client.getServiceCode(), time, token);
        HttpRequest request = HttpUtil.createGet(url);
        HttpResponse response = request.execute();
        if (HttpStatus.HTTP_OK != response.getStatus()) {
            System.err.println("请求失败");
            return false;
        } else {
            this.zentaosid = response.getCookieValue("zentaosid");
            StaticLog.info("禅道登录凭证：{}", this.zentaosid);
        }
        return true;
    }

    /**
     * 检查状态
     *
     * @return 登录状态是否正常
     */
    public synchronized boolean checkStatus() {
        try {
            HttpRequest httpRequest = createTestUrl();
            HttpResponse execute = httpRequest.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                return false;
            }
            String body = execute.body();
            String string = Convert.unicodeToStr(body);
            if (!StrUtil.contains(string, Constant.LOGIN_OVERTIME)) {
                return true;
            }
        } catch (Exception ignored) {

        }
        // 登录状态异常后尝试登录
        return login(account);
    }

    public HttpRequest createTestUrl() {
        String fullUrl = client.getServiceUrl();
        HttpRequest request = HttpUtil.createGet(fullUrl);
        setDefault(request, fullUrl);
        request.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
        request.header("Upgrade-Insecure-Requests", "1");
        return request;
    }

    public HttpRequest createGet(String url) {
        checkStatus();
        String fullUrl = client.getServiceUrl() + url;
        HttpRequest request = HttpUtil.createGet(fullUrl);
        setDefault(request, fullUrl);
        return request;
    }

    public HttpRequest createGetForHtml(String url) {
        checkStatus();
        String fullUrl = client.getServiceUrl() + url;
        HttpRequest request = HttpUtil.createGet(fullUrl);
        setDefault(request, fullUrl);
        request.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
        request.header("Upgrade-Insecure-Requests", "1");
        return request;
    }

    public HttpRequest createPost(String url) {
        checkStatus();
        String fullUrl = client.getServiceUrl() + url;
        HttpRequest request = HttpUtil.createPost(fullUrl);
        setDefault(request, fullUrl);
        return request;
    }

    public HttpRequest createPostForHtml(String url) {
        checkStatus();
        String fullUrl = client.getServiceUrl() + url;
        HttpRequest request = HttpUtil.createPost(fullUrl);
        setDefault(request, fullUrl);
        request.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
        request.header("Upgrade-Insecure-Requests", "1");
        return request;
    }

    public void setDefault(HttpRequest request, String url) {
        request.setConnectionTimeout(DEFAULT_CONNECT_TIMEOUT);
        request.setReadTimeout(DEFAULT_READ_TIMEOUT);
        request.header("Accept", "application/json, text/javascript, */*; q=0.01");
        request.header("Accept-Encoding", "gzip, deflate");
        request.header("Accept-Language", "zh-CN,zh;q=0.9");
        request.header("Connection", "keep-alive");
        request.header("Host", client.getServiceUrl().replaceAll("http[s]?://", ""));
        request.header("Origin", client.getServiceUrl());
        request.header("Referer", url);
        request.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36");
        request.header("X-Requested-With", "XMLHttpRequest");
        request.cookie("zentaosid=" + this.zentaosid);
    }
}
